package com.health.action;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.sf.json.JSONArray;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.ServletActionContext;

import com.health.constant.Constants;
import com.health.dto.UserDTO;
import com.health.exceptions.ValidatorException;
import com.health.exceptions.ValidatorLevelException;
import com.health.model.LoginInfo;
import com.health.model.User;
import com.health.service.IUserService;
import com.health.util.SecureUtils;

/**
 * @author DirkMurphy
 * 
 * @blog http://www.cnblogs.com/dirkmurphyjava/
 * 
 * @date
 * 
 * @introduction
 */
public class UserAction extends ActionInterface
{

	private static Log			log			= LogFactory.getLog(UserAction.class);
	private UserDTO				userDTO;
	private User				user;
	// Spring inject it
	private IUserService		userService;
	// use static method
	private SecureUtils			secureUtils;

	private HttpServletResponse	response	= null;
	private HttpServletRequest	request		= null;

	private static PrintWriter	out			= null;
	private String				msg			= "";
	// about paging
	private Integer				start		= null;
	private Integer				limit		= null;

	static
	{}

	/**
	 * user register logic method
	 * */
	public String register()
	{

		request = ServletActionContext.getRequest();
		response = ServletActionContext.getResponse();
		try
		{
			out = response.getWriter();
			int exist = userService.checkUserExist(userDTO.getEmail());
			if (exist > 0)
			{
				msg = "{success:false , errors:'this email address has been registered '}";
				out.write(msg);
				log.warn("same email address register again");
				return null;
			}
		}
		catch (IOException e1)
		{
			log.error(e1);
		}
		int status = Constants.STATUS_NORMAL;// 0:normal 1:forbidden
		int permission = Constants.PERMISSION_NORMAL;// 0:admin 1:normal
		int loginCount = 0;
		userDTO.setStatus(status);// the initial value is 0
		userDTO.setPermission(permission);// the initial value is 0
		userDTO.setRegistertime(new java.sql.Date((new java.util.Date()).getTime()));// initial
																						// value
		userDTO.setLoginCount(loginCount);
		String password = userDTO.getPassword();
		if (null != password)
		{
			password = secureUtils.BASE64Encode(password);
			userDTO.setPassword(password);
		}
		try
		{
			user = userDTO.convertDtoToPO(userDTO);
			userService.insert(user);
			msg = "{success:true}";
			out.write(msg);
		}
		catch (ValidatorLevelException e)
		{
			log.error(e);
			msg = "{success:false , errors:'validator level exception!'}";
			out.write(msg);
		}
		catch (ValidatorException e)
		{
			e.printStackTrace();
			msg = "{success:false , errors:'data invalid!'}";
			out.write(msg);
		}
		return null;
	}

	/**
	 * user login logic method
	 * */
	public String login()
	{
		request = ServletActionContext.getRequest();
		response = ServletActionContext.getResponse();
		try
		{
			out = response.getWriter();
		}
		catch (IOException e)
		{
			log.error(e);
		}
		String password = userDTO.getPassword();
		if (null != password)
		{
			password = secureUtils.BASE64Encode(password);
			userDTO.setPassword(password);
		}
		user = userDTO.convertDtoToPO(userDTO);
		Object retObj = userService.login(user);
		if (null != retObj && retObj instanceof User)
		{
			User retUser = (User) retObj;
			if (retUser.getPermission() == 0)
			{
				// if admin(0)
				msg = "{success:true , ret:'" + Constants.PERMISSION_ADMIN
						+ "'}";
			}
			else if (retUser.getPermission() == 1)
			{
				// if normal user(1)
				msg = "{success:true , ret:'" + Constants.PERMISSION_NORMAL
						+ "'}";
			}
			if (retUser.getLoginCount() != 0)
			{
				retUser.setLoginCount(0);
				userService.update(retUser);
			}
			out.write(msg);
			log.info("login success : " + user.getEmail());
			user = userService.selectListAll(user).get(0);
			HttpSession session = request.getSession();
			LoginInfo loginInfo = new LoginInfo(user.getId(),
					user.getName(),
					user.getEmail(),
					user.getPermission(),
					user.getStatus());
			session.setAttribute(Constants.LOGININFO, loginInfo);
		}
		else if (null != retObj && retObj instanceof String)
		{
			String retStr = (String) retObj;
			log.warn("user login error");
			if (retStr == Constants.EMAIL_NOT_FOUND)
			{
				msg = "{success:false , errors:'email not found'}";
			}
			else if (retStr == Constants.ACCOUNT_LOCKED)
			{
				msg = "{success:false , errors:'because of many times to login error!<br>account locked!<br>plz contact our servicer'}";
			}
			else if (retStr == Constants.PASSWORD_NOT_CORRECT)
			{
				msg = "{success:false , errors:'password incorrect'}";
				User u = new User();
				u.setEmail(user.getEmail());
				u = (User) userService.selectListAll(u).get(0);
				u.setLoginCount(u.getLoginCount() + 1);
				userService.update(u);
			}
			out.write(msg);
		}
		out.close();
		return null;
	}

	/**
	 * query logic method with paging
	 * */
	public String selectListPage()
	{
		start = this.getStart();
		limit = this.getLimit();
		userDTO.setStart(start);
		userDTO.setLimit(limit);
		request = ServletActionContext.getRequest();
		response = ServletActionContext.getResponse();
		user = userDTO.convertDtoToPO(userDTO);
		List<User> userList = new ArrayList<User>();
		userList = userService.selectListPage(user);
		List<User> userListAll = userService.selectListAll(user);
		JSONArray jsonList = JSONArray.fromObject(userList, jsonConfig);
		String resText = "{data:" + jsonList.toString() + ",totalCount:"
				+ userListAll.size() + "}";
		out.write(resText);
		System.out.println("resultText : " + resText);
		return null;
	}

	/**
	 * logout method
	 * 
	 * @throws IOException
	 * */
	public String logout()
	{
		request = ServletActionContext.getRequest();
		response = ServletActionContext.getResponse();
		HttpSession session = request.getSession();
		if (session != null)
		{
			session.removeAttribute(Constants.LOGININFO);
		}
		else
		{
			try
			{
				out = response.getWriter();
				out.write("{success:false , errors:'F5/Ctrl+F5 or restart your web browser'}");
			}
			catch (IOException e)
			{
				e.printStackTrace();
				out.write("{success:false , errors:'F5/Ctrl+F5 or restart your web browser'}");
			}
			finally
			{
				out.close();
			}
		}
		return null;
	}

	/**
	 * getters and setters
	 * */
	public UserDTO getUserDTO()
	{
		return userDTO;
	}

	public void setUserDTO(UserDTO userDTO)
	{
		this.userDTO = userDTO;
	}

	public User getUser()
	{
		return user;
	}

	public void setUser(User user)
	{
		this.user = user;
	}

	public Integer getStart()
	{
		return start;
	}

	public void setStart(Integer start)
	{
		this.start = start;
	}

	public Integer getLimit()
	{
		return limit;
	}

	public void setLimit(Integer limit)
	{
		this.limit = limit;
	}

	public IUserService getUserService()
	{
		return userService;
	}

	public void setUserService(IUserService userService)
	{
		this.userService = userService;
	}

}
